package com.shycloud.mido.member.pattern;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.Objects;
import java.util.function.Function;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.shycloud.mido.common.core.exception.BusinessException;
import com.shycloud.mido.common.core.util.SpringContextHolder;
import com.shycloud.mido.member.api.entity.MultiAssist;
import com.shycloud.mido.member.api.entity.MultiAssistRecord;
import com.shycloud.mido.member.api.util.Constant;
import com.shycloud.mido.member.api.vo.MultiAssistRecordVO;
import com.shycloud.mido.member.service.MultiAssistRecordService;
import com.shycloud.mido.member.service.MultiAssistService;

/** 
 * @Description: TODO
 * @author baiqiang.
 * @date 2021年7月14日 上午10:57:53 
 * @ClassName: SubjectBuilder
 *  
 */
public class SubjectBuilder extends StrategyBuilder{
	
	@Override
	public SubjectBuilder buildOptAssign() {
		strategyMap.put(Constant.ASSIST_SUBJECT_MASTER, (payload) -> {
			commonStrategy(payload, (item) -> {
				MultiAssistService multiAssistService = SpringContextHolder.getBean(MultiAssistService.class);
				MultiAssistRecordVO vo = item.getMultiAssistRecordVO();
				LambdaQueryWrapper<MultiAssist> multiAssistQW =
				        Wrappers.<MultiAssist>lambdaQuery()
				        .eq(MultiAssist::getSubject, vo.getSubject())
				        .eq(MultiAssist::getOptId, vo.getOptId())
				        .eq(MultiAssist::getDelFlag, Constant.DEL_FLAG);
				MultiAssist multiAssistPO = multiAssistService.getOne(multiAssistQW);
				return multiAssistPO;
			});
		});
		//TODO 工作室暂时不给分配 未来在开发
		strategyMap.put(Constant.ASSIST_SUBJECT_OPT, strategyMap.get(Constant.ASSIST_SUBJECT_MASTER));
		return this;
	}
	@Override
	public SubjectBuilder buildOrgAssign() {
		strategyMap.put(Constant.ASSIST_SUBJECT_ORG, (payload) -> {
			commonStrategy(payload, (item) -> {
				MultiAssistService multiAssistService = SpringContextHolder.getBean(MultiAssistService.class);
				MultiAssistRecordVO vo = item.getMultiAssistRecordVO();
				LambdaQueryWrapper<MultiAssist> multiAssistQW =
				        Wrappers.<MultiAssist>lambdaQuery()
				        .eq(MultiAssist::getSubject, vo.getSubject())
				        .eq(MultiAssist::getOrgId, vo.getOrgId())
				        .eq(MultiAssist::getDelFlag, Constant.DEL_FLAG);
				MultiAssist multiAssistPO = multiAssistService.getOne(multiAssistQW);
				return multiAssistPO;
			});
		});
		strategyMap.put(Constant.ASSIST_SUBJECT_STUDIO, strategyMap.get(Constant.ASSIST_SUBJECT_ORG));
		return this;
	}

	@Override
	public SubjectBuilder buildTeacherAssign() {
		strategyMap.put(Constant.ASSIST_SUBJECT_TEACHER, (payload) -> {
			commonStrategy(payload, (item) -> {
				MultiAssistService multiAssistService = SpringContextHolder.getBean(MultiAssistService.class);
				MultiAssistRecordVO vo = item.getMultiAssistRecordVO();
				LambdaQueryWrapper<MultiAssist> multiAssistQW =
				        Wrappers.<MultiAssist>lambdaQuery()
				        .eq(MultiAssist::getSubject, vo.getSubject())
				        .eq(MultiAssist::getTeacherId, vo.getTeacherId())
				        .eq(MultiAssist::getDelFlag, Constant.DEL_FLAG);
				MultiAssist multiAssistPO = multiAssistService.getOne(multiAssistQW);
				return multiAssistPO;
			});
		});
		return this;
	}
	
	/* 特殊处理学生 需要计算开始和结束 计时天天帮 开通时间为 +1天后 末尾时间设置为23：59：59秒
	 * @see com.shycloud.mido.member.pattern.Builder#buildStudentTable()
	 */
	@Override
	public SubjectBuilder buildStudentOpening() {
		strategyMap.put(Constant.ASSIST_SUBJECT_STUDENT, (payload) -> {
			MultiAssistRecordVO vo = payload.getMultiAssistRecordVO();
			//获取开通几个月 记录
			Integer monthly = vo.getMonthly();
			//1增加 2减少 
			String type = vo.getType();
					
			MultiAssistRecordService multiAssistRecordService = SpringContextHolder.getBean(MultiAssistRecordService.class);
			MultiAssistService multiAssistService = SpringContextHolder.getBean(MultiAssistService.class);
			
			LocalDateTime now = LocalDateTime.now();
			//发起方处理 给学生开通只能为
			LambdaQueryWrapper<MultiAssist> multiAssistLaunchQW =
			        Wrappers.<MultiAssist>lambdaQuery()
			        .eq(MultiAssist::getSubject, vo.getSubjectLaunch())
			        .eq(MultiAssist::getDelFlag, Constant.DEL_FLAG);
			
			MultiAssistRecord multiAssistRecordLaunch = new MultiAssistRecord();
			multiAssistRecordLaunch.setSubject(payload.getMultiAssistRecordVO().getSubjectLaunch());
			if (StringUtils.equalsAny(multiAssistRecordLaunch.getSubject(), Constant.ASSIST_SUBJECT_MASTER,Constant.ASSIST_SUBJECT_OPT)) {
				multiAssistLaunchQW.eq(MultiAssist::getOptId, Integer.valueOf(vo.getCommonId()));
				multiAssistRecordLaunch.setOptId(Integer.valueOf(vo.getCommonId()));
				throw new BusinessException("代理商无法给学生开通");
			}else if(StringUtils.equalsAny(multiAssistRecordLaunch.getSubject(), Constant.ASSIST_SUBJECT_ORG,Constant.ASSIST_SUBJECT_STUDIO)) {
				multiAssistLaunchQW.eq(MultiAssist::getOrgId, vo.getCommonId());
				multiAssistRecordLaunch.setOrgId(Integer.valueOf(vo.getCommonId()));
			}else if(StringUtils.equals(multiAssistRecordLaunch.getSubject(), Constant.ASSIST_SUBJECT_TEACHER)) {
				multiAssistLaunchQW.eq(MultiAssist::getTeacherId, vo.getCommonId());
				multiAssistRecordLaunch.setTeacherId(vo.getCommonId());
			}else if(StringUtils.equals(multiAssistRecordLaunch.getSubject(), Constant.ASSIST_SUBJECT_STUDENT)) {
				//当前无业务 学生无法分配
				multiAssistLaunchQW.eq(MultiAssist::getStudentId, vo.getCommonId());
				multiAssistRecordLaunch.setStudentId(vo.getCommonId());
				throw new BusinessException("学生无法开通");
			}
			MultiAssist multiAssistLaunchPO = multiAssistService.getOne(multiAssistLaunchQW);
			
			//更新天天帮时长 反向处理
			if (Objects.isNull(multiAssistLaunchPO)) {
				throw new BusinessException("当前用户数据不存在");
			}else {
				//更新天天帮时长
				if (StringUtils.equals(Constant.ASSIST_TYPE_PLUS, type)) {
					if (multiAssistLaunchPO.getMonthly() - monthly < 0) {
						throw new BusinessException("时长不足无法处理");
					}
					multiAssistRecordLaunch.setType(Constant.ASSIST_TYPE_MINUS);
					multiAssistLaunchPO.setMonthly(multiAssistLaunchPO.getMonthly() - monthly);
//					multiAssistLaunchPO.setDuration(multiAssistLaunchPO.getMonthly() * 30);
				}else if (StringUtils.equals(Constant.ASSIST_TYPE_MINUS, type)){
					multiAssistLaunchPO.setMonthly(multiAssistLaunchPO.getMonthly() + monthly);
//					multiAssistLaunchPO.setDuration(multiAssistLaunchPO.getMonthly() * 30);
					multiAssistRecordLaunch.setType(Constant.ASSIST_TYPE_PLUS);
				}else {
					throw new BusinessException("没有分配类型");
				}
				multiAssistLaunchPO.setUpdateTime(now);
				multiAssistLaunchPO.setUpdateUser(String.valueOf(vo.getMemberId()));
				multiAssistService.updateById(multiAssistLaunchPO);
				//外键ID
				multiAssistRecordLaunch.setAssistId(multiAssistLaunchPO.getId());
			}
			
			//插入天天帮 记录
			multiAssistRecordLaunch.setScope(vo.getScope());
			multiAssistRecordLaunch.setMonthly(monthly);
			multiAssistRecordLaunch.setCreateTime(now);
			multiAssistRecordLaunch.setCreateUser(String.valueOf(vo.getMemberId()));
			multiAssistRecordLaunch.setUpdateTime(now);
			multiAssistRecordLaunch.setUpdateUser(String.valueOf(vo.getMemberId()));
			multiAssistRecordLaunch.setDelFlag(Constant.DEL_FLAG);
			multiAssistRecordLaunch.setFkRecordId("-1");//发起方标记
			multiAssistRecordService.save(multiAssistRecordLaunch);
			
			//接收方处理
			MultiAssistRecord multiAssistRecord = new MultiAssistRecord();
			MultiAssist multiAssist = new MultiAssist();
			
			BeanUtils.copyProperties(vo, multiAssistRecord);
			multiAssistRecord.setFkRecordId(multiAssistRecordLaunch.getId());//发起方ID
			BeanUtils.copyProperties(vo, multiAssist);
			
			LocalDateTime endTime = now.plusMonths(monthly);
			long between = ChronoUnit.DAYS.between(now, endTime);
			multiAssistRecord.setDuration((int)between);
			
			LambdaQueryWrapper<MultiAssist> multiAssistQW =
			        Wrappers.<MultiAssist>lambdaQuery()
			        .eq(MultiAssist::getSubject, vo.getSubject())
			        .eq(MultiAssist::getStudentId, vo.getStudentId())
			        .eq(MultiAssist::getDelFlag, Constant.DEL_FLAG);
			MultiAssist multiAssistPO = multiAssistService.getOne(multiAssistQW);
			//无需消费时间 所有没有开始和结束时长 只有月份
			if (Objects.isNull(multiAssistPO)) {
				//插入天天帮
				multiAssist.setCreateTime(now);
				multiAssist.setCreateUser(String.valueOf(vo.getMemberId()));
				multiAssist.setUpdateTime(now);
				multiAssist.setUpdateUser(String.valueOf(vo.getMemberId()));
				multiAssist.setDelFlag(Constant.DEL_FLAG);
				//更新天天帮时长
				if (StringUtils.equals(Constant.ASSIST_TYPE_PLUS, type)) {
					multiAssist.setMonthly(vo.getMonthly());
					//开通计算开始和结束日期
					multiAssist.setStartTime(now);
					//结束时间设置23：59：59
					LocalTime localTime = LocalTime.of(23, 59, 59);
					LocalDateTime endTimeLast = endTime.toLocalDate().atTime(localTime);
					multiAssist.setEndTime(endTimeLast);
					multiAssist.setDuration((int)between);
				}else if (StringUtils.equals(Constant.ASSIST_TYPE_MINUS, type)){
					throw new BusinessException("时长不足无法处理");
				}else {
					throw new BusinessException("没有分配类型");
				}
				multiAssistService.save(multiAssist);
				//外键ID
				multiAssistRecord.setAssistId(multiAssist.getId());
			}else {
				//更新天天帮时长
				if (StringUtils.equals(Constant.ASSIST_TYPE_PLUS, type)) {
					//判断是否到期
					LocalDateTime endTimePO = multiAssistPO.getEndTime();
					if (now.isAfter(endTimePO)) {
						//过期重新 重置月份不在连续
						multiAssistPO.setMonthly(monthly);
						//开通计算开始和结束日期  如果过期则重置 不过期则续费
						multiAssist.setStartTime(now);
						//结束时间设置23：59：59
						LocalTime localTime = LocalTime.of(23, 59, 59);
						LocalDateTime endTimeLast = endTime.toLocalDate().atTime(localTime);
						multiAssistPO.setEndTime(endTimeLast);
						multiAssistPO.setDuration((int)between);
					}else {
						//未过期 续期
						multiAssistPO.setMonthly(multiAssistPO.getMonthly() + monthly);
						//结束时间设置23：59：59
						LocalTime localTime = LocalTime.of(23, 59, 59);
						LocalDateTime endTimeLast = multiAssistPO.getEndTime().plusMonths(monthly).toLocalDate().atTime(localTime);
						multiAssistPO.setEndTime(endTimeLast);
						multiAssistPO.setDuration((int)ChronoUnit.DAYS.between(multiAssistPO.getStartTime(), endTimeLast));
					}
					
				}else if (StringUtils.equals(Constant.ASSIST_TYPE_MINUS, type)){
					//判断是否到期
					LocalDateTime endTimePO = multiAssistPO.getEndTime();
					if (now.isAfter(endTimePO)) {
						//过期 无法减少
						throw new BusinessException("过期无法减少时长");
					}
					LocalDateTime endTimeCheck = endTimePO.minusMonths(monthly);
					if (now.isAfter(endTimeCheck)) {
						//扣除时长后 无法减少
						throw new BusinessException("不足够扣除时长");
					}
					//未过期 结束- 扣除时长
					LocalDateTime endTimeLast = multiAssistPO.getEndTime().minusMonths(monthly);
					multiAssistPO.setEndTime(endTimeLast);
					multiAssistPO.setDuration((int)ChronoUnit.DAYS.between(multiAssistPO.getStartTime(), endTimeLast));
					multiAssistPO.setMonthly(multiAssistPO.getMonthly() - monthly);
				}else {
					throw new BusinessException("没有分配类型");
				}
				multiAssistPO.setUpdateTime(now);
				multiAssistPO.setUpdateUser(String.valueOf(vo.getMemberId()));
				multiAssistService.updateById(multiAssistPO);
				//multiAssistService.updateById(multiAssist);
				//外键ID
				multiAssistRecord.setAssistId(multiAssistPO.getId());
			}
			
			//插入天天帮 记录
			multiAssistRecord.setCreateTime(now);
			multiAssistRecord.setCreateUser(String.valueOf(vo.getMemberId()));
			multiAssistRecord.setUpdateTime(now);
			multiAssistRecord.setUpdateUser(String.valueOf(vo.getMemberId()));
			multiAssistRecord.setDelFlag(Constant.DEL_FLAG);
			multiAssistRecordService.save(multiAssistRecord);
		});
		return this;
	}
	
    
}